package com.example.seckill.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.seckill.domain.ItemDO;
import com.example.seckill.domain.ItemStockDO;
import com.example.seckill.error.BusinessException;
import com.example.seckill.error.CommonErrorEnum;
import com.example.seckill.mapper.ItemStockMapper;
import com.example.seckill.mappstruct.ItemMap;
import com.example.seckill.service.ItemService;
import com.example.seckill.mapper.ItemMapper;
import com.example.seckill.service.PromoService;
import com.example.seckill.service.model.ItemModel;
import com.example.seckill.service.model.PromoModel;
import com.example.seckill.service.model.PromoStatusEnum;
import com.example.seckill.validator.ValidateResult;
import com.example.seckill.validator.ValidatorComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 */
@SuppressWarnings("ALL")
@Service
@Slf4j
public class ItemServiceImpl extends ServiceImpl<ItemMapper, ItemDO> implements ItemService {
    @Autowired
    private ItemStockMapper itemStockMapper;
    @Autowired
    private ValidatorComponent validatorComponent;
    @Autowired
    private ItemService itemService;
    @Autowired
    private PromoService promoService;

    @Override
    @Transactional
    public ItemModel insert(ItemModel itemModel) {
        //校验
        ValidateResult validate = validatorComponent.validate(itemModel);
        if (validate.getHasError()) {
            throw new BusinessException(CommonErrorEnum.PARAMETER_VALIDATION_ERROR, validate.getErrorMsgs());
        }
        //转换
        ItemDO itemDO = ItemMap.INSTANCE.Model2DO(itemModel);
        this.baseMapper.insert(itemDO);
        itemModel.setId(itemDO.getId());

        ItemStockDO itemStockDO = new ItemStockDO();
        itemStockDO.setStock(itemModel.getStock());
        itemStockDO.setItemId(itemModel.getId());
        itemStockMapper.insert(itemStockDO);
        //返回创建完的对象
        return this.findById(itemModel.getId());//有点6
    }

    @Override
    public ItemModel findById(Integer id) {
        ItemDO itemDO = this.baseMapper.selectById(id);
        ItemStockDO itemStockDO = itemStockMapper.selectOne(new QueryWrapper<ItemStockDO>().lambda().eq(ItemStockDO::getItemId, id));
        ItemModel itemModel = convert2Model(itemDO, itemStockDO);
        PromoModel promoModel = promoService.findByItemId(id);
        if (promoModel != null) {
            LocalDateTime now = LocalDateTimeUtil.now();
            if (now.isBefore(promoModel.getStartDate())) {
                //秒杀还未开始
                itemModel.setPromoStatusEnum(PromoStatusEnum.BEFORE_PROMO);
                itemModel.setPromoModel(promoModel);
            }else if(now.isAfter(promoModel.getEndDate())){
                //秒杀结束
                itemModel.setPromoStatusEnum(PromoStatusEnum.AFTER_PROMO);
            }else {
                //秒杀开始
                itemModel.setPromoStatusEnum(PromoStatusEnum.IN_PROMO);
                itemModel.setPromoModel(promoModel);
            }
        }

        return itemModel;
    }

    @Override
    public List<ItemModel> findAll() {
        List<ItemDO> itemDOS = this.baseMapper.selectList(new QueryWrapper<ItemDO>().lambda().orderByDesc(ItemDO::getSales));
        List<ItemModel> itemModels = itemDOS.stream().map(item -> {
            ItemModel itemModel = ItemMap.INSTANCE.DO2Model(item);
            ItemStockDO itemStockDO = itemStockMapper.selectOne(new QueryWrapper<ItemStockDO>().lambda().eq(ItemStockDO::getItemId, item.getId()));
            return convert2Model(item, itemStockDO);

        }).collect(Collectors.toList());
        return itemModels;
    }

    @Override
    @Transactional
    public Boolean decreaseStock(Integer itemId, Integer amount) {
        return itemStockMapper.decrease(itemId,amount)>0;
    }

    @Override
    public void increaseSales(Integer itemId, Integer amount) {
        this.baseMapper.increaseSales(itemId,amount);
    }

    //聚合封装
    private ItemModel convert2Model(ItemDO itemDO, ItemStockDO itemStockDO) {
        ItemModel itemModel = ItemMap.INSTANCE.DO2Model(itemDO);
        itemModel.setStock(itemStockDO.getStock());
        return itemModel;
    }
}




